/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view.gui;

import controller.exceptions.InvalidVersionException;
import controller.exceptions.ItemAlreadyRemovedException;
import controller.net.NetControllerClient;
import filesystem.exceptions.InvalidModelItemException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
import model.*;
import sun.swing.MenuItemLayoutHelper;

/**
 *
 * @author Bro
 */
public class AppView extends javax.swing.JFrame {

    private NetControllerClient client;
    private JTable table;
    private boolean isAlbum, isArtist, isGenre, isTrack;
    private TableTrack tabTrack;
    private TableAlbum tabAlbum;
    private TableArtist tabArtist;
    private TableGenre tabGenre;
    private int boundX = 0;
    private int boundY = 0;
    private boolean isAdd = false;
    private boolean isSearch = false;
    private ModelItem item = null;

    /**
     * Creates new form AppView
     */
    public AppView(NetControllerClient ncc) {
        client = ncc;
        initComponents();
        countInfo.setVisible(false);
        calculateBounds();
        setBounds(boundX, boundY, getWidth(), getHeight());
        setTitle("Music library");
    }

    private void calculateBounds() {
        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        boundX = (int) ((screenSize.getWidth() - getWidth()) / 2);
        if (boundX < 0) {
            boundX = 0;
        }
        boundY = (int) ((screenSize.getHeight() - getHeight()) / 2);
        if (boundY < 0) {
            boundY = 0;
        }
    }

    private void calculateBounds(JDialog dialog) {
        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        boundX = (int) ((screenSize.getWidth() - dialog.getWidth()) / 2);
        if (boundX < 0) {
            boundX = 0;
        }
        boundY = (int) ((screenSize.getHeight() - dialog.getHeight()) / 2);
        if (boundY < 0) {
            boundY = 0;
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        editDialog = new javax.swing.JDialog();
        okButton = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        sizeLabel = new javax.swing.JLabel();
        sizeTextField = new javax.swing.JTextField();
        albumLabel = new javax.swing.JLabel();
        genreLabel = new javax.swing.JLabel();
        lengthTextField = new javax.swing.JTextField();
        artistLabel = new javax.swing.JLabel();
        lengthLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        artistComboBox = new javax.swing.JComboBox();
        albumComboBox = new javax.swing.JComboBox();
        genreComboBox = new javax.swing.JComboBox();
        removeMenu = new javax.swing.JPopupMenu();
        removeMenuItem = new javax.swing.JMenuItem();
        footPanel = new javax.swing.JPanel();
        addButton = new javax.swing.JButton();
        countInfo = new javax.swing.JLabel();
        countLabel = new javax.swing.JLabel();
        searchButton = new javax.swing.JButton();
        infoPanel = new javax.swing.JPanel();
        mainMenu = new javax.swing.JMenuBar();
        jMenu_model = new javax.swing.JMenu();
        jMenuItem_track = new javax.swing.JMenuItem();
        jMenuItem_artist = new javax.swing.JMenuItem();
        jMenuItem_album = new javax.swing.JMenuItem();
        jMenuItem_genre = new javax.swing.JMenuItem();

        okButton.setText("OK");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        nameLabel.setText("Name:");

        sizeLabel.setText("Size:");

        albumLabel.setText("Album:");

        genreLabel.setText("Genre:");

        artistLabel.setText("Artist:");

        lengthLabel.setText("Length:");

        artistComboBox.setEditable(true);

        albumComboBox.setEditable(true);

        genreComboBox.setEditable(true);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(genreLabel)
                    .addComponent(albumLabel)
                    .addComponent(artistLabel)
                    .addComponent(lengthLabel)
                    .addComponent(sizeLabel)
                    .addComponent(nameLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lengthTextField)
                    .addComponent(sizeTextField)
                    .addComponent(nameTextField)
                    .addComponent(artistComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(albumComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(genreComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(20, 20, 20))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(nameLabel)
                    .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(artistLabel)
                    .addComponent(artistComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(albumLabel)
                    .addComponent(albumComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(4, 4, 4)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(genreLabel)
                    .addComponent(genreComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lengthTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lengthLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(sizeLabel))
                .addContainerGap())
        );

        javax.swing.GroupLayout editDialogLayout = new javax.swing.GroupLayout(editDialog.getContentPane());
        editDialog.getContentPane().setLayout(editDialogLayout);
        editDialogLayout.setHorizontalGroup(
            editDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(editDialogLayout.createSequentialGroup()
                .addGap(167, 167, 167)
                .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(177, Short.MAX_VALUE))
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        editDialogLayout.setVerticalGroup(
            editDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(editDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(okButton)
                .addGap(16, 16, 16))
        );

        removeMenuItem.setText("jMenuItem1");
        removeMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeMenuItemActionPerformed(evt);
            }
        });
        removeMenu.add(removeMenuItem);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        addButton.setText("Add new item");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        countInfo.setText("    ");

        countLabel.setText("Count:");

        searchButton.setText("Search");
        searchButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout footPanelLayout = new javax.swing.GroupLayout(footPanel);
        footPanel.setLayout(footPanelLayout);
        footPanelLayout.setHorizontalGroup(
            footPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, footPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(countLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(countInfo)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        footPanelLayout.setVerticalGroup(
            footPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(footPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(footPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(countInfo)
                    .addComponent(countLabel))
                .addGap(34, 34, 34))
            .addGroup(footPanelLayout.createSequentialGroup()
                .addGroup(footPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addButton)
                    .addComponent(searchButton))
                .addGap(0, 0, Short.MAX_VALUE))
        );

        infoPanel.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                infoPanelComponentResized(evt);
            }
        });

        javax.swing.GroupLayout infoPanelLayout = new javax.swing.GroupLayout(infoPanel);
        infoPanel.setLayout(infoPanelLayout);
        infoPanelLayout.setHorizontalGroup(
            infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 651, Short.MAX_VALUE)
        );
        infoPanelLayout.setVerticalGroup(
            infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 310, Short.MAX_VALUE)
        );

        jMenu_model.setText("Model");

        jMenuItem_track.setText("Track");
        jMenuItem_track.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_trackActionPerformed(evt);
            }
        });
        jMenu_model.add(jMenuItem_track);

        jMenuItem_artist.setText("Artist");
        jMenuItem_artist.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_artistActionPerformed(evt);
            }
        });
        jMenu_model.add(jMenuItem_artist);

        jMenuItem_album.setText("Album");
        jMenuItem_album.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_albumActionPerformed(evt);
            }
        });
        jMenu_model.add(jMenuItem_album);

        jMenuItem_genre.setText("Genre");
        jMenuItem_genre.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_genreActionPerformed(evt);
            }
        });
        jMenu_model.add(jMenuItem_genre);

        mainMenu.add(jMenu_model);

        setJMenuBar(mainMenu);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(footPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(infoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(infoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(47, 47, 47)
                .addComponent(footPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jMenuItem_trackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem_trackActionPerformed
        if (client.getClientSocket() == null) {
            JOptionPane.showMessageDialog(this, "Failed to set the connection",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        setTitle("Music library. Tracks");
        infoPanel.removeAll();
        isAlbum = false;
        isArtist = false;
        isGenre = false;
        isTrack = true;
        ArrayList myColumns = new ArrayList();
        ArrayList receivedData = null;
        myColumns.add("№");
        myColumns.add("Name");
        myColumns.add("Artist");
        myColumns.add("Album");
        myColumns.add("Genre");
        myColumns.add("Length");
        myColumns.add("Size");
        try {
            if (!isSearch) {
                receivedData = client.selectItems(NetControllerClient.type.TRACK, null);
            } else {
                receivedData = client.selectItems(NetControllerClient.type.TRACK, item);
            }
            tabTrack = new TableTrack(receivedData, myColumns);
            table = new JTable(tabTrack);
            JScrollPane jscrlp = new JScrollPane(table);
            table.setPreferredScrollableViewportSize(
                    new Dimension(infoPanel.getWidth(), infoPanel.getHeight()));
            table.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        item = tabTrack.getSelectedItem(table.getSelectedRow());
                        showEditDialog();
                    }
                    if (SwingUtilities.isRightMouseButton(e)) {
                        int row = table.rowAtPoint(e.getPoint());
                        table.setRowSelectionInterval(row, row);
                        item = tabTrack.getSelectedItem(table.getSelectedRow());
                        removeMenuItem.setText("Remove track");
                        removeMenu.show(table, e.getX(), e.getY());
                    }
                }
            });

            infoPanel.setLayout(new BorderLayout());
            infoPanel.add(jscrlp, BorderLayout.CENTER);
            countInfo.setVisible(true);
            countInfo.setText(((Integer) receivedData.size()).toString());
        } catch (IOException ex) {
            Logger.getLogger(AppView.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.revalidate();
    }//GEN-LAST:event_jMenuItem_trackActionPerformed

    private void jMenuItem_artistActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem_artistActionPerformed
        if (client.getClientSocket() == null) {
            JOptionPane.showMessageDialog(this, "Failed to set the connection",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        setTitle("Music library. Artists");
        infoPanel.removeAll();
        isAlbum = false;
        isArtist = true;
        isGenre = false;
        isTrack = false;
        ArrayList myColumns = new ArrayList();
        ArrayList receivedData = null;
        myColumns.add("№");
        myColumns.add("Name");
        try {
            if (!isSearch) {
                receivedData = client.selectItems(NetControllerClient.type.ARTIST, null);
            } else {
                receivedData = client.selectItems(NetControllerClient.type.ARTIST, item);
            }
            tabArtist = new TableArtist(receivedData, myColumns);
            table = new JTable(tabArtist);
            TableColumn c = table.getColumnModel().getColumn(0);
            c.setWidth(20);
            c.setPreferredWidth(20);
            JScrollPane jscrlp = new JScrollPane(table);
            table.setPreferredScrollableViewportSize(
                    new Dimension(infoPanel.getWidth(), infoPanel.getHeight()));
            table.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        item = tabArtist.getSelectedItem(table.getSelectedRow());
                        showEditDialog();
                    }
                    if (SwingUtilities.isRightMouseButton(e)) {
                        int row = table.rowAtPoint(e.getPoint());
                        table.setRowSelectionInterval(row, row);
                        item = tabArtist.getSelectedItem(table.getSelectedRow());
                        removeMenuItem.setText("Remove artist");
                        removeMenu.show(table, e.getX(), e.getY());
                    }
                }
            });

            infoPanel.setLayout(new BorderLayout());
            infoPanel.add(jscrlp, BorderLayout.CENTER);
            countInfo.setVisible(true);
            countInfo.setText(((Integer) receivedData.size()).toString());
        } catch (IOException ex) {
            Logger.getLogger(AppView.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.revalidate();
    }//GEN-LAST:event_jMenuItem_artistActionPerformed

    private void jMenuItem_albumActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem_albumActionPerformed
        if (client.getClientSocket() == null) {
            JOptionPane.showMessageDialog(this, "Failed to set the connection",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        setTitle("Music library. Albums");
        infoPanel.removeAll();
        isAlbum = true;
        isArtist = false;
        isGenre = false;
        isTrack = false;
        ArrayList myColumns = new ArrayList();
        ArrayList receivedData = null;
        myColumns.add("№");
        myColumns.add("Name");
        try {
            if (!isSearch) {
                receivedData = client.selectItems(NetControllerClient.type.ALBUM, null);
            } else {
                receivedData = client.selectItems(NetControllerClient.type.ALBUM, item);
            }
            tabAlbum = new TableAlbum(receivedData, myColumns);
            table = new JTable(tabAlbum);
            JScrollPane jscrlp = new JScrollPane(table);
            table.setPreferredScrollableViewportSize(
                    new Dimension(infoPanel.getWidth(), infoPanel.getHeight()));
            table.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        item = tabAlbum.getSelectedItem(table.getSelectedRow());
                        showEditDialog();
                    }
                    if (SwingUtilities.isRightMouseButton(e)) {
                        int row = table.rowAtPoint(e.getPoint());
                        table.setRowSelectionInterval(row, row);
                        item = tabAlbum.getSelectedItem(table.getSelectedRow());
                        removeMenuItem.setText("Remove album");
                        removeMenu.show(table, e.getX(), e.getY());
                    }
                }
            });

            infoPanel.setLayout(new BorderLayout());
            infoPanel.add(jscrlp, BorderLayout.CENTER);
            countInfo.setVisible(true);
            countInfo.setText(((Integer) receivedData.size()).toString());
        } catch (IOException ex) {
            Logger.getLogger(AppView.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.revalidate();
    }//GEN-LAST:event_jMenuItem_albumActionPerformed

    private void jMenuItem_genreActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem_genreActionPerformed
        if (client.getClientSocket() == null) {
            JOptionPane.showMessageDialog(this, "Failed to set the connection",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        setTitle("Music library. Genres");
        infoPanel.removeAll();
        isAlbum = false;
        isArtist = false;
        isGenre = true;
        isTrack = false;
        ArrayList myColumns = new ArrayList();
        ArrayList receivedData = null;
        myColumns.add("№");
        myColumns.add("Name");
        try {
            if (!isSearch) {
                receivedData = client.selectItems(NetControllerClient.type.GENRE, null);
            } else {
                receivedData = client.selectItems(NetControllerClient.type.GENRE, item);
            }
            tabGenre = new TableGenre(receivedData, myColumns);
            table = new JTable(tabGenre);
            JScrollPane jscrlp = new JScrollPane(table);
            table.setPreferredScrollableViewportSize(
                    new Dimension(infoPanel.getWidth(), infoPanel.getHeight()));
            table.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        item = tabGenre.getSelectedItem(table.getSelectedRow());
                        showEditDialog();
                    }
                    if (SwingUtilities.isRightMouseButton(e)) {
                        int row = table.rowAtPoint(e.getPoint());
                        table.setRowSelectionInterval(row, row);
                        item = tabGenre.getSelectedItem(table.getSelectedRow());
                        removeMenuItem.setText("Remove genre");
                        removeMenu.show(table, e.getX(), e.getY());
                    }
                }
            });

            infoPanel.setLayout(new BorderLayout());
            infoPanel.add(jscrlp, BorderLayout.CENTER);
            countInfo.setVisible(true);
            countInfo.setText(((Integer) receivedData.size()).toString());
        } catch (IOException ex) {
            Logger.getLogger(AppView.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.revalidate();

    }//GEN-LAST:event_jMenuItem_genreActionPerformed

    private void infoPanelComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_infoPanelComponentResized
    }//GEN-LAST:event_infoPanelComponentResized

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        if (!(isAlbum || isArtist || isGenre || isTrack)) {
            return;
        }
        isAdd = true;
        item = createItem();
        showEditDialog();
        isAdd = false;
    }//GEN-LAST:event_addButtonActionPerformed

    private void fillItemComboBoxes() {
        if (client.getClientSocket() == null) {
            JOptionPane.showMessageDialog(this, "Failed to set the connection",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        ArrayList receivedData = null;
        try {
            receivedData = client.selectItems(NetControllerClient.type.ARTIST, null);
        } catch (IOException ex) {
            //TODO
        }
        artistComboBox.removeAllItems();
        for (Object i : receivedData) {
            artistComboBox.addItem((Artist) i);
        }
        artistComboBox.setSelectedIndex(-1);

        try {
            receivedData = client.selectItems(NetControllerClient.type.ALBUM, null);
        } catch (IOException ex) {
            //TODO
        }
        albumComboBox.removeAllItems();
        for (Object i : receivedData) {
            albumComboBox.addItem((Album) i);
        }
        albumComboBox.setSelectedIndex(-1);

        try {
            receivedData = client.selectItems(NetControllerClient.type.GENRE, null);
        } catch (IOException ex) {
            //TODO
        }
        genreComboBox.removeAllItems();
        for (Object i : receivedData) {
            genreComboBox.addItem((Genre) i);
        }
        genreComboBox.setSelectedIndex(-1);
    }

    private ModelItem createItem() {
        if (isAlbum) {
            return new Album();
        }
        if (isArtist) {
            return new Artist();
        }
        if (isGenre) {
            return new Genre();
        }
        if (isTrack) {
            return new Track();
        }
        return null;
    }

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        String name = nameTextField.getText();
        String artist = ((JTextField) artistComboBox.getEditor().getEditorComponent()).getText();
        String album = ((JTextField) albumComboBox.getEditor().getEditorComponent()).getText();
        String genre = ((JTextField) genreComboBox.getEditor().getEditorComponent()).getText();
        String length = lengthTextField.getText();
        String size = sizeTextField.getText();

        if (name.contains("\\") || album.contains("\\") || artist.contains("\\")
                || genre.contains("\\")) {
            JOptionPane.showMessageDialog(editDialog, "Forbidden symbol \"\\\"",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (name.contains("/") || album.contains("/") || artist.contains("/")
                || genre.contains("/")) {
            JOptionPane.showMessageDialog(editDialog, "Forbidden symbol \"/\"",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (name.equals("") && !isSearch) {
            JOptionPane.showMessageDialog(editDialog, "Not all the fields are filled in",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (!isSearch && item instanceof Track && (name.equals("")
                || artist.equals("") || album.equals("")
                || genre.equals("") || lengthTextField.getText().equals("")
                || sizeTextField.getText().equals(""))) {
            JOptionPane.showMessageDialog(editDialog, "Not all the fields are filled in",
                    "Warning!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        item.setName((name.equals("")) ? null : name);
        if (item instanceof Track) {
            if (!isSearch) {
                try {
                    Integer.valueOf(length);
                    Integer.valueOf(size);
                } catch (NumberFormatException e) {
                    JOptionPane.showMessageDialog(editDialog, "Fields \"Length\" and \"Size\" must contain numbers only",
                            "Warning!", JOptionPane.WARNING_MESSAGE);
                    return;
                }
            }
            ((Track) item).setAlbum(new Album(album.equals("") ? null : album));
            ((Track) item).setArtist(new Artist(artist.equals("") ? null : artist));
            ((Track) item).setGenre(new Genre(genre.equals("") ? null : genre));
            if (!length.equals("")) {
                ((Track) item).setLength(Integer.parseInt(length));
            }
            if (!size.equals("")) {
                ((Track) item).setSize(Integer.parseInt(size));
            }
        }

        if (isSearch) {
            isAdd = false;
            updateTable();
            isSearch = false;
            editDialog.dispose();
            return;
        }

        if (isAdd) {
            try {
                client.execute(NetControllerClient.operation.ADD,
                        getItemType(), item);
            } catch (IOException ex) {
            } catch (InvalidVersionException ex) {
                JOptionPane.showMessageDialog(editDialog, "Another client already chenged the editing item",
                        "Warning!", JOptionPane.WARNING_MESSAGE);
            } catch (ItemAlreadyRemovedException ex) {
            }
        } else {
            try {
                client.execute(NetControllerClient.operation.EDIT,
                        getItemType(), item);
            } catch (IOException ex) {
            } catch (InvalidVersionException ex) {
                JOptionPane.showMessageDialog(editDialog, "Another client already chenged the editing item",
                        "Warning!", JOptionPane.WARNING_MESSAGE);
            } catch (ItemAlreadyRemovedException ex) {
                JOptionPane.showMessageDialog(editDialog, "Another client already removed the editing item",
                        "Warning!", JOptionPane.WARNING_MESSAGE);
            }
        }
        isAdd = false;
        isSearch = false;
        updateTable();
        editDialog.dispose();
    }//GEN-LAST:event_okButtonActionPerformed

    private void removeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeMenuItemActionPerformed

        int answer = JOptionPane.showConfirmDialog(table,
                "Do you realy want to remove this item?");
        if (answer == 0) {
            try {
                client.execute(NetControllerClient.operation.REMOVE, getItemType(), item);
            } catch (InvalidModelItemException ex) {
            } catch (IOException ex) {
            } catch (InvalidVersionException ex) {
            } catch (ItemAlreadyRemovedException ex) {
            } finally {
                updateTable();
            }
        }
    }//GEN-LAST:event_removeMenuItemActionPerformed

    private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
        if (!(isAlbum || isArtist || isGenre || isTrack)) {
            return;
        }
        isSearch = true;
        item = createItem();
        showEditDialog();
        isSearch = false;
    }//GEN-LAST:event_searchButtonActionPerformed

    private void updateTable() {
        if (isAlbum) {
            jMenuItem_albumActionPerformed(null);
        }
        if (isArtist) {
            jMenuItem_artistActionPerformed(null);
        }
        if (isGenre) {
            jMenuItem_genreActionPerformed(null);
        }
        if (isTrack) {
            jMenuItem_trackActionPerformed(null);
        }
    }

    private NetControllerClient.type getItemType() {
        if (item instanceof Album) {
            return NetControllerClient.type.ALBUM;
        }
        if (item instanceof Artist) {
            return NetControllerClient.type.ARTIST;
        }
        if (item instanceof Genre) {
            return NetControllerClient.type.GENRE;
        }
        if (item instanceof Track) {
            return NetControllerClient.type.TRACK;
        }
        return null;
    }

    private void showEditDialog() {
        editDialog.setModal(true);
        editDialog.setResizable(false);
        if (isAdd) {
            editDialog.setTitle("Add item");
        } else {
            editDialog.setTitle("Edit item");
        }

        nameTextField.setText((isAdd || isSearch) ? null : item.getName());

        if (isTrack) {
            editDialog.setSize(420, 300);
            fillItemComboBoxes();

            ((JTextField) artistComboBox.getEditor().getEditorComponent()).setText((isAdd || isSearch) ? null : ((Track) item).getArtist().toString());
            ((JTextField) albumComboBox.getEditor().getEditorComponent()).setText((isAdd || isSearch) ? null : ((Track) item).getAlbum().toString());
            ((JTextField) genreComboBox.getEditor().getEditorComponent()).setText((isAdd || isSearch) ? null : ((Track) item).getGenre().toString());
            lengthTextField.setText((isAdd || isSearch)
                    ? null : Integer.toString(((Track) item).getLength()));
            sizeTextField.setText((isAdd || isSearch)
                    ? null : Integer.toString(((Track) item).getSize()));

            artistLabel.setVisible(true);
            artistComboBox.setVisible(true);
            albumLabel.setVisible(true);
            albumComboBox.setVisible(true);
            genreLabel.setVisible(true);
            genreComboBox.setVisible(true);
            lengthLabel.setVisible(true);
            lengthTextField.setVisible(true);
            sizeLabel.setVisible(true);
            sizeTextField.setVisible(true);
        } else {
            editDialog.setSize(420, 130);
            artistLabel.setVisible(false);
            artistComboBox.setVisible(false);
            albumLabel.setVisible(false);
            albumComboBox.setVisible(false);
            genreLabel.setVisible(false);
            genreComboBox.setVisible(false);
            lengthLabel.setVisible(false);
            lengthTextField.setVisible(false);
            sizeLabel.setVisible(false);
            sizeTextField.setVisible(false);
        }
        calculateBounds(editDialog);
        editDialog.setBounds(boundX, boundY, editDialog.getWidth(), editDialog.getHeight());
        if (isSearch) {
            editDialog.setTitle("Search items");
            okButton.setText("Search");
        }
        editDialog.setVisible(true);
        okButton.setText("OK");
    }

    /**
     * this method must be in main
     *
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(AppView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(AppView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(AppView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(AppView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                NetControllerClient client = new NetControllerClient();
                new AppView(client).setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JComboBox albumComboBox;
    private javax.swing.JLabel albumLabel;
    private javax.swing.JComboBox artistComboBox;
    private javax.swing.JLabel artistLabel;
    private javax.swing.JLabel countInfo;
    private javax.swing.JLabel countLabel;
    private javax.swing.JDialog editDialog;
    private javax.swing.JPanel footPanel;
    private javax.swing.JComboBox genreComboBox;
    private javax.swing.JLabel genreLabel;
    private javax.swing.JPanel infoPanel;
    private javax.swing.JMenuItem jMenuItem_album;
    private javax.swing.JMenuItem jMenuItem_artist;
    private javax.swing.JMenuItem jMenuItem_genre;
    private javax.swing.JMenuItem jMenuItem_track;
    private javax.swing.JMenu jMenu_model;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel lengthLabel;
    private javax.swing.JTextField lengthTextField;
    private javax.swing.JMenuBar mainMenu;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JButton okButton;
    private javax.swing.JPopupMenu removeMenu;
    private javax.swing.JMenuItem removeMenuItem;
    private javax.swing.JButton searchButton;
    private javax.swing.JLabel sizeLabel;
    private javax.swing.JTextField sizeTextField;
    // End of variables declaration//GEN-END:variables
}
